package com.cskaoyan.config;

import com.cskaoyan.shiro.AdminRealm;
import com.cskaoyan.shiro.CustomAuthenticator;
import com.cskaoyan.shiro.CustomWebSessionManager;
import com.cskaoyan.shiro.WxRealm;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;


@Configuration
public class ShiroConfig {


    /**
     * 配置授权管理 ShiroFilterFactoryBean ---->依赖于 securityManager
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager){
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);

        /**
         * 配置无需 认证 即可访问的url  除了这几个 url 其他都要 验证权限
         */
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        //后台的匿名接口
        filterChainDefinitionMap.put("/admin/auth/login","anon");
        filterChainDefinitionMap.put("/admin/auth/info","anon");
        filterChainDefinitionMap.put("/admin/auth/logout","anon");
        //前台的匿名接口
        filterChainDefinitionMap.put("/wx/auth/**","anon");
        filterChainDefinitionMap.put("/wx/home/index","anon");
        filterChainDefinitionMap.put("/wx/goods/**","anon");
        filterChainDefinitionMap.put("/wx/search/**","anon");
        filterChainDefinitionMap.put("/wx/comment/**","anon");
        filterChainDefinitionMap.put("/wx/coupon/list","anon");
        filterChainDefinitionMap.put("/wx/storage/upload","anon");
        filterChainDefinitionMap.put("/wx/brand/**","anon");
        filterChainDefinitionMap.put("/wx/topic/**","anon");
        filterChainDefinitionMap.put("/**","authc");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

        return shiroFilterFactoryBean;
    }

    /**
     * 配置核心组件  SecurityManager
     * 配置 sessionManager 自定义sessionManager 解决跨域访问 sessionId 不同问题
     *      realm
     *      authenticator 自定义认证器  重写了验证权限方法 doAuthenticate
     */
    @Bean
    public DefaultWebSecurityManager securityManager(AdminRealm adminRealm, WxRealm wxRealm, CustomAuthenticator authenticator){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setSessionManager(sessionManager());
        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(adminRealm);
        realms.add(wxRealm);
        securityManager.setRealms(realms);
        securityManager.setAuthenticator(authenticator);
        return securityManager;
    }

    /**
     * DefaultWebSessionManager  重写getSessionId方法 解决跨域访问下 sessionId不同的问题
     */
    @Bean
    public DefaultWebSessionManager sessionManager(){
        CustomWebSessionManager sessionManager = new CustomWebSessionManager();
        return sessionManager;
    }

    /**
     * 注册自定义认证器组件，并配置其realms 信息
     */
    @Bean
    public CustomAuthenticator authenticator(AdminRealm adminRealm, WxRealm wxRealm){

        CustomAuthenticator customAuthenticator = new CustomAuthenticator();
        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(adminRealm);
        realms.add(wxRealm);
        customAuthenticator.setRealms(realms);
        return customAuthenticator;
    }

    /**
     * AuthorizationAttributeSourceAdvisor 通知器  ---依赖核心组件 securityManager
     * 声明式注解鉴权 所需要的组件
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager defaultWebSecurityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(defaultWebSecurityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
